/*
 * Copyright (C) 2011 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.bkkit.redlung;

import java.util.HashMap;
import java.util.Set;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;

public class PlayerListener extends org.bukkit.event.player.PlayerListener
		implements Runnable {
	private final String SOURCE_CLASS = getClass().getName();
	private final RadiatedPlayers radiatedPlayers;
	private final Config config;

	public PlayerListener(final RadiatedPlayers radiatedPlayers,
			final Config config) {
		super();
		this.radiatedPlayers = radiatedPlayers;
		this.config = config;
	}

	@Override
	public void onPlayerJoin(PlayerJoinEvent event) {
		LogWrapper.entering(SOURCE_CLASS, "onPlayerJoin", event.getPlayer());
		this.radiatedPlayers.playerJoin(event.getPlayer());
		LogWrapper.exiting(SOURCE_CLASS, "onPlayerJoin", event.getPlayer());
	}

	@Override
	public void onPlayerRespawn(PlayerRespawnEvent event) {
		LogWrapper.entering(SOURCE_CLASS, "onPlayerRespawn", event.getPlayer());
		this.radiatedPlayers.setRadiationLevel(event.getPlayer(), 0);
		LogWrapper.exiting(SOURCE_CLASS, "onPlayerRespawn", event.getPlayer());
	}

	@Override
	public void onPlayerInteract(PlayerInteractEvent event) {
		if (isMaybeEatAction(event)) {
			final ItemStack itemStack = event.getItem();
			if (itemStack != null) {
				final Material material = itemStack.getType();
				if (material == Material.RAW_FISH) {
					heal(event.getPlayer(), this.config.getRadiationStrength());
				}
				if (material == Material.COOKED_FISH) {
					heal(event.getPlayer(),
							this.config.getRadiationStrength() * 3);
				}
			}
		}
	}

	private boolean isMaybeEatAction(PlayerInteractEvent event) {
		final Action action = event.getAction();
		if (action != null) {
			if (Action.RIGHT_CLICK_AIR == action) {
				return true;
			}
			if (Action.RIGHT_CLICK_BLOCK == action) {
				final Block clickedBlock = event.getClickedBlock();
				final Material clickedBlockType = clickedBlock.getType();
				switch (clickedBlockType) {
				case CHEST:
				case BED_BLOCK:
				case CAKE:
				case DIODE_BLOCK_OFF:
				case DISPENSER:
				case FURNACE:
				case LEVER:
				case TRAP_DOOR:
				case WOODEN_DOOR:
				case WORKBENCH:
					return false;
				default:
					return true;
				}
			}
		}
		return false;
	}

	private void heal(final Player player, int amount) {
		if (this.radiatedPlayers.getAccumulatedAmount(player) > 0) {
			this.radiatedPlayers.heal(player, amount);
		}
	}

	@Override
	public void run() {
		HashMap<Player, RadiationAccumulator> sickPlayers = this.radiatedPlayers
				.getSickPlayers();
		final Set<Player> keySet = sickPlayers.keySet();
		for (final Player player : keySet) {
			if (player.isOnline() && !player.isDead()) {
				final RadiationAccumulator radiationAccumulator = sickPlayers
						.get(player);
				int damage = radiationAccumulator.getAccumulatedRadiation() / 2;
				if (damage > 0) {
					LogWrapper.fine("Dealing: " + damage
							+ " points of damage to player: " + player);
					player.damage(damage);
					player.sendMessage(this.config.getSickMessage(damage));
				}
			}
		}
	}
}
